#define LAND_GRAPHICS_CORE

#include "init.h"

struct LandFrame {
	LandRef ref;
	LandFrameSlot* slots;
	unsigned count;
	unsigned cap;
	LandTexture* texture;
};

static void
expandSlot(LandFrame* frame) {
	unsigned cap = frame->cap * 2;
	LandFrameSlot* slots = malloc(sizeof(LandFrameSlot) * cap);
	memcpy(slots, frame->slots, sizeof(LandFrameSlot) * frame->count);
	free(frame->slots);
	frame->cap = cap;
	frame->slots = slots;
}

static void
freeFrame(LandRef* ref) {
	LandFrame* frame = (LandFrame*)ref;
	landReleaseRef(frame->texture);
}

LAND_GRAPHICS_API LandFrame*
landNewFrame(LandTexture* texture, unsigned cap) {
	landRetainRef(texture);
	LandFrame* frame = landNewRef(sizeof(LandFrame), freeFrame);
	frame->texture = texture;
	frame->cap = cap;
	frame->count = 0;
	frame->slots = malloc(sizeof(LandFrameSlot) * cap);
	return frame;
}

LAND_GRAPHICS_API unsigned
landRegFrameSlot(LandFrame* frame, LandFloat width,
	LandFloat height, LandVector* rect, LandVector* border) {
	if (frame->count >= frame->cap) {
		expandSlot(frame);
	}
	unsigned index = frame->count++;
	LandFrameSlot* slot = &frame->slots[index];
	slot->width = width;
	slot->height = height;
	slot->rect = *rect;
	slot->border = *border;
	LandFloat tw = (LandFloat)frame->texture->width;
	LandFloat th = (LandFloat)frame->texture->height;
	LandVector uv = {
		(rect->left + border->left) / tw,
		(rect->top + border->top) / th,
		((rect->left + rect->right) - border->right) / tw,
		((rect->top + rect->bottom) - border->bottom) / th,
	};
	slot->uv = uv;
	return index;
}

LAND_GRAPHICS_API LandFrameSlot*
landGetFrameSlot(LandFrame* frame, unsigned index) {
	if (index >= frame->count) {
		return NULL;
	}

	LandFrameSlot* slot = &frame->slots[index];
	slot->texture = frame->texture;
	return slot;
}